﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<array>
#include<string>
#include<algorithm>
using namespace std;
// 编译报错：失败原因是未解除分配已分配的存储
// 这⾥可以看到虽然⽀持了constexpr函数中new/delete
// 但是还要求必须编译器释放内存，所以实际库⾥⾯constexpr化还相对有限
//constexpr std::vector<int> create_vector() {
// std::vector<int> v{ 1, 2, 3 }; // 编译期构造
// v.push_back(4); // 编译期操作
//
// return v;
//}
constexpr auto sort_example() {
	std::array<int, 5> arr{ 5, 3, 4, 1, 2 };
	std::sort(arr.begin(), arr.end()); // 编译期排序
	return arr;
} 
void test1()
{
	// constexpr auto vec = create_vector(); // 编译期⽣成{1,2,3}
	// constexpr string s1("111111111111");
	// constexpr vector<int> v1(10, 1);
	constexpr array<int, 10> a1 = { 3,2,1,4,5 };
	vector<int> v2 = { 3,2,1,4,5 };
	sort(v2.begin(), v2.end());
	//sort(a1.begin(), a1.end());
	auto it1 = find(v2.begin(), v2.end(), 3);
	// 相对有限⽀持的constexpr
	constexpr auto sorted = sort_example(); // {1,2,3,4,5}
	constexpr auto it2 = find(a1.begin(), a1.end(), 4);
	static_assert(*it2 == 4, "编译期查找");
}
//try _catch语句完善
constexpr int safe_divide(int a, int b) {
	try {
		if (b == 0)
			throw "Division by zero";
		else
			return a / b;
	} catch(...) {
		return 0; // 编译期异常处理
	}
} 
void test2()
{
	constexpr int val1 = safe_divide(10, 2); // 5
	constexpr int val2 = safe_divide(10, 0); // 报错
}
// constexpr 联合体(union)
constexpr union Data
{
	int i;
	float f;
	constexpr Data(int val) : i(val) {} // 初始化整数成员
	constexpr Data(float val) : f(val) {} // 初始化浮点成员
};
void test3()
{
	constexpr Data d1(42); // 活跃成员是i
	constexpr Data d2(3.14f); // 活跃成员是f
	//constexpr float temp = d1.f; // 错误：访问⾮活跃成员（编译失败）
	constexpr int temp = d1.i;
}
//constexpr 可变(mutable)成员
class A {
	mutable int _i;
	int _j;
public:
	constexpr A(int i, int j)
		:_i(i)
		, _j(j)
	{
	}
	constexpr int Func() const
	{
		++_i; // 可以修改
		// ++_j; // 不能修改
		return _i + _j;
	}
};
void test4()
{
	constexpr A aa(1, 1);
	constexpr int ret = aa.Func();
}
//constexpr 虚函数⽀持
class Base {
public:
	virtual constexpr int value() const { return 1; }
};
class Derived : public Base {
public:
	constexpr int value() const override { return 2; }
};
constexpr int get_value(const Base& b) {
	return b.value(); // 编译期多态调⽤
}
void test5() 
{
	constexpr int ret1 = get_value(Base());
	constexpr int ret2 = get_value(Derived());
}
int main()
{
	test1();
	test2();
	test3();
	test4();
	test5();
	return 0;
}